package com.zcsy.manage.service.push.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zcsy.commons.constants.Constants;
import com.zcsy.commons.constants.DistributionConstants;
import com.zcsy.commons.constants.OwnerConstants;
import com.zcsy.commons.constants.PushConstants;
import com.zcsy.commons.constants.ShopConstants;
import com.zcsy.commons.model.RequestJson;
import com.zcsy.commons.sms.dlife.HttpUtils;
import com.zcsy.commons.util.DateUtils;
import com.zcsy.commons.util.MD5Util;
import com.zcsy.manage.model.base.CommonToken;
import com.zcsy.manage.model.mall.OrderInfo;
import com.zcsy.manage.model.news.NoticeInfo;
import com.zcsy.manage.persistence.base.CommonTokenDao;
import com.zcsy.manage.persistence.mall.OrderInfoDao;
import com.zcsy.manage.persistence.system.RoleCellDao;
import com.zcsy.manage.persistence.system.UserDao;
import com.zcsy.manage.service.mall.IOrderInfoService;
import com.zcsy.manage.service.news.INoticeInfoService;
import com.zcsy.manage.service.push.IPushService;

/**
 * @Title:PushServiceImpl @Package： com.zcsy.manage.service.push.impl
 * @Description:推送实现类
 * @author wangj
 * @date 2016年6月7日下午3:48:07
 * @version 1.0
 * @see JDK1.7.0_67
 * @Copyright: 2016 武汉恒数利通技术有限公司 All rights reserved.ss
 */
@Service
public class PushServiceImpl implements IPushService {

	/**
	 * 请求返回值
	 */
	public static final int RESULT_SUCCESS = 0; // 成功
	public static final int RESULT_PARAMETER_ERROR = -1; // 参数错误

	/** 信鸽推送接口地址 */
	public static final String XG_PUSH_URL = "openapi.xg.qq.com/v2/push/account_list";
	/** 信鸽推送完整接口地址 */
	public static final String XG_PUSH_ALL_URL = "http://" + XG_PUSH_URL;
	public static final String DEFAULT_CHARSET = "UTF-8";
	/** 向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境 */
	public static final String iOS_ENVIRENMENT = "1"; 

	@Autowired
	private OrderInfoDao orderDao;

	@Autowired
	private RoleCellDao rolecell;

	@Autowired
	private UserDao userdao;

	@Autowired
	private IOrderInfoService orderInfoService;

	@Autowired
	private CommonTokenDao commonTokenDao;

	@Autowired
	INoticeInfoService noticeInfoService;

	/*
	 * (non-Javadoc)
	 * 
	 * @author: zt
	 * 
	 * @date: 2016年8月23日
	 * 
	 * @param
	 * 
	 * @return
	 * 
	 * @see
	 * com.zcsy.manage.service.push.PushService#pushDistributionMsg(java.lang.
	 * String, int)
	 */
	@Override
	public String pushDistributionMsg(String orderId, int pushType) {

		// 当前时间
		SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String TimeString = time.format(new java.util.Date());

		// 用户账号存储数组
		List<String> accounts = new ArrayList<String>();

		OrderInfo orderInfo = orderDao.selectOrderByPrimaryKey(orderId);

		RequestJson mesJson = new RequestJson();

		mesJson.setResultCode(RESULT_SUCCESS);
		mesJson.setSuccess(true);
		
		// 给客户端的消息
		JSONObject msContent = new JSONObject();
		msContent.put("messageType", pushType); 
		if (pushType == Constants.PUSH_TYPE_RUSH) {
			// 平台有新的订单order_number待配送；
			// 设置推送账户类型
			List<String> menuValues = new ArrayList<String>();
			// 抢单人员
			menuValues.add(Constants.DISTRIBUTION_ONE);

			// 查询有以上权限的用户登录名列表
			accounts = orderInfoService.selectAccountsFromOrderByRoles(orderId, menuValues);

			// 给客户端的消息
			msContent.put("msg", "推送成功！");
			
			msContent.put("orderNumber", orderInfo.getOrderNumber());
			msContent.put("title", "新订单");
			msContent.put("content", "<html><body> 有新的订单<font color='red'>" + orderInfo.getOrderNumber()
					+ "</font>待配送！ </body></html>");
			msContent.put("time", TimeString);
			mesJson.setObj(msContent);

		} else if (pushType == Constants.PUSH_TYPE_DISTRIBUTED) {
			// 管理员把订单order_number派给了你，请完成配送;
			accounts.add(orderInfoService.selectOrderByPrimaryKey(orderId).getSenderAccount());

			// 给客户端的消息
			msContent.put("msg", "推送成功！");
			msContent.put("orderNumber", orderInfo.getOrderNumber());
			msContent.put("title", "抢单员收单");
			msContent.put("content", "<html><body> 有订单<font color='red'>" + orderInfo.getOrderNumber()
					+ "</font>派给了你，请完成配送！ </body></html>");
			msContent.put("time", TimeString);
			mesJson.setObj(msContent);

		} else if (pushType == Constants.PUSH_TYPE_CONFIRMED) {
			// 您派送的订单order_number业主已确认收货；
			accounts.add(orderInfoService.selectOrderByPrimaryKey(orderId).getSenderAccount());

			// 给客户端的消息
			msContent.put("msg", "推送成功！");
			msContent.put("orderNumber", orderInfo.getOrderNumber());
			msContent.put("title", "业主收货");
			msContent.put("content", "<html><body> 您派送的订单<font color='red'>" + orderInfo.getOrderNumber()
					+ "</font>业主已确认收货！ </body></html>");
			msContent.put("time", TimeString);
			mesJson.setObj(msContent);

		} else if (pushType == Constants.PUSH_TYPE_DISTRIBUTION)  {
			// 有订单order_number超时，需配送；
			// 设置推送账户类型
			List<String> menuIds = new ArrayList<String>();
			// 派单人员
			menuIds.add(Constants.DISTRIBUTION_TWO);
			// 查询有配送权限的用户登录名列表
			accounts = orderInfoService.selectAccountsFromOrderByRoles(orderId, menuIds);
			
			
			msContent.put("msg", "推送成功！");
			msContent.put("messageType", 2); // 1.抢单消息，2.派单消息
			msContent.put("orderNumber", orderInfo.getOrderNumber());
			msContent.put("title", "管理员派单");
			msContent.put("content", "<html><body> 有订单<font color='red'>" + orderInfo.getOrderNumber()
					+ "</font>超时，需配送！ </body></html>");
			msContent.put("time", TimeString);
			mesJson.setObj(msContent);

		}

		// 根据用户登录名列表查token对象列表
		if(null != accounts && accounts.size() > 0) {
		    List<CommonToken> tokens = commonTokenDao.selectByAccounts(accounts);
		    mesJson.setMsg(msContent.getString("title"));
		    return pushToClient(mesJson, tokens, DistributionConstants.ACCESSIDANDROID, DistributionConstants.SECRETKEYANDROID,
		            DistributionConstants.ACCESSIDIOS, DistributionConstants.SECRETKEYIOS);
		} else {
		    return null;
		}
	}

	/**
	 * @Description 根据key的顺序（字典中的顺序）对Map进行排序，并拼接输出(仅本类中的pushDistributionMsg方法需要)
	 * @param params
	 *            Map集合
	 * @return 拼接字符串
	 * @author liuying 1075817474@qq.com
	 * @date 2016年6月16日
	 * @see
	 */
	public String sortParams(Map<String, String> params) {
		StringBuffer ParamsString = new StringBuffer();

		List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(params.entrySet());

		// 排序
		Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
			public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
				return ((o1.getKey()).compareTo(o2.getKey()));
			}
		});

		for (int i = 0; i < infoIds.size(); i++) {
			Entry<String, String> ent = infoIds.get(i);
			ParamsString.append(ent.getKey() + "=" + ent.getValue());
		}

		return ParamsString.toString();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @author: zt
	 * 
	 * @date: 2016年8月23日
	 * 
	 * @param
	 * 
	 * @return
	 * 
	 * @see
	 * com.zcsy.manage.service.push.PushService#pushOwnerMsg(java.lang.String,
	 * com.zcsy.commons.constants.PushConstants.OwnerPushType)
	 */
	@Override
	public String pushOwnerMsg(String objId, int pushType){
		List<CommonToken> tokens = null;
		
		// 当前时间
		String timeString = DateUtils.datetimeFormat.format(new Date());

		RequestJson mesJson = new RequestJson();

		mesJson.setResultCode(RESULT_SUCCESS);
		mesJson.setSuccess(true);
		mesJson.setMsg("推送成功！");
		// 给客户端的消息
		JSONObject msContent = new JSONObject();

		msContent.put("messageType", pushType);
		msContent.put("objId", objId);

		msContent.put("time", timeString);
		mesJson.setObj(msContent);

		switch (pushType) {
		case PushConstants.PUSH_TYPE_OWNER_CELL_NOTICE:
			//小区通知，推送给所有有房屋在此小区的用户
			NoticeInfo info = noticeInfoService.selectByPrimaryKey(objId);
			msContent.put("title", "小区通知");
			msContent.put("content", info.getTitle());
			
			tokens = commonTokenDao.selectUsersTokenByCellId(info.getCellId());
			break;
		case PushConstants.PUSH_TYPE_OWNER_ORDER:
			OrderInfo orderInfo = orderDao.selectOrderByPrimaryKey(objId);
			if(orderInfo == null){
				return null;
			}
			ArrayList<String> accounts = new ArrayList<String>();
			accounts.add(orderInfo.getUserAccount());
			tokens = commonTokenDao.selectByAccounts(accounts);
			switch (orderInfo.getState()) {
			case Constants.ORDER_UNSEND:
				// 已接订单
				msContent.put("title", "商家已接单");
				msContent.put("content", "您的订单已被接，订单编号：" + orderInfo.getOrderNumber());
				break;
			case Constants.ORDER_DISTRIBUTION_ING:
				// 配送中
				msContent.put("title", "订单已发货");
				msContent.put("content", "您的订单已发货，订单编号：" + orderInfo.getOrderNumber());
				break;
			case Constants.ORDER_CANCEL:
				// 被取消
				msContent.put("title", "订单已被取消");
				msContent.put("content", "您的订单已被取消，订单编号：" + orderInfo.getOrderNumber());
				break;
			}
			break;
		default:
			break;
		}
		mesJson.setMsg(msContent.getString("title"));
		return pushToClient(mesJson, tokens, OwnerConstants.ACCESSIDANDROID, OwnerConstants.SECRETKEYANDROID,
				OwnerConstants.ACCESSIDIOS, OwnerConstants.SECRETKEYIOS);
	}
	
	/*
	 * (non-Javadoc)
	 * @author: zt
	 * @date: 2016年8月26日
	 * @param     
	 * @return   
	 * @see com.zcsy.manage.service.push.IPushService#pushOwnerFeesMsg(java.lang.String, java.lang.String, int)
	 */
	@Override
	public String pushOwnerFeesMsg(String title, String content, int pushType){
		List<CommonToken> tokens = null;
		
		// 当前时间
		String timeString = DateUtils.datetimeFormat.format(new Date());

		RequestJson mesJson = new RequestJson();

		mesJson.setResultCode(RESULT_SUCCESS);
		mesJson.setSuccess(true);
		mesJson.setMsg("推送成功！");
		// 给客户端的消息
		JSONObject msContent = new JSONObject();

		msContent.put("messageType", pushType);
		msContent.put("title", title);
		msContent.put("content", content);
		msContent.put("time", timeString);
		mesJson.setObj(msContent);

		mesJson.setMsg(msContent.getString("title"));
		return pushToClient(mesJson, tokens, OwnerConstants.ACCESSIDANDROID, OwnerConstants.SECRETKEYANDROID,
				OwnerConstants.ACCESSIDIOS, OwnerConstants.SECRETKEYIOS);
	}
	
	/*
	 * (non-Javadoc)
	 * @author: zt
	 * @date: 2016年8月24日
	 * @param     
	 * @return   
	 * @see com.zcsy.manage.service.push.IPushService#pushShopMsg(java.lang.String)
	 */
	@Override
	public String pushShopMsg(String orderId){

		List<CommonToken> tokens = null;
		
		// 当前时间
		String timeString = DateUtils.datetimeFormat.format(new Date());

		RequestJson mesJson = new RequestJson();

		mesJson.setResultCode(RESULT_SUCCESS);
		mesJson.setSuccess(true);
		mesJson.setMsg("推送成功！");
		// 给客户端的消息
		JSONObject msContent = new JSONObject();

		msContent.put("objId", orderId);
		msContent.put("time", timeString);
		msContent.put("messageType", PushConstants.PUSH_TYPE_SHOP_ORDER);
		
		mesJson.setObj(msContent);
		
		OrderInfo orderInfo = orderDao.selectOrderByPrimaryKey(orderId);
		if(orderInfo == null){
			return null;
		}
		tokens = commonTokenDao.selectUsersTokenByShopId(orderInfo.getShopId());
		
		switch (orderInfo.getState()) {
		case Constants.ORDER_UNSEND:
			msContent.put("title", "新订单");
			msContent.put("content", "您有新的订单，订单编号：" + orderInfo.getOrderNumber());
			mesJson.setMsg("新订单");
			break;
		}
		
		return pushToClient(mesJson, tokens, ShopConstants.ACCESSIDANDROID, ShopConstants.SECRETKEYANDROID,
				ShopConstants.ACCESSIDIOS, ShopConstants.SECRETKEYIOS);
	
	}

	/**
	 * 推送内容到指定客户端
	 * 
	 * @param content 推送内容
	 * @param tokens 推送的用户token
	 * @param accessIdAndroid 信鸽android accessId
	 * @param secretKeyAndroid 信鸽android secretKey
	 * @param accessIdIOS 信鸽iOS accessId
	 * @param secretKeyIOS 信鸽iOS secretKey
	 * @return
	 * @author: zt
	 * @date: 2016年8月23日
	 */
	private String pushToClient(RequestJson content, List<CommonToken> tokens, String accessIdAndroid,
			String secretKeyAndroid, String accessIdIOS, String secretKeyIOS) {
		if(tokens == null || tokens.size() == 0){
			return null;
		}
		
		// 存储在Android客户端登录的tokens
		StringBuffer tokensAndroids = new StringBuffer();
		String tokensAndroid = null;

		// 存储在iOS客户端登录的tokens
		StringBuffer tokensIOSs = new StringBuffer();
		String tokensIOS = null;
		// 将tokens列表转换成字符串
		if (tokens.size() != 0) {
			for (CommonToken token : tokens) {
				if (token.getPlatformType() == Constants.ANDROID) {
					tokensAndroids = tokensAndroids.append("\"");
					tokensAndroids = tokensAndroids.append(token.getToken());
					tokensAndroids = tokensAndroids.append("\",");
				} else {
					tokensIOSs = tokensIOSs.append("\"");
					tokensIOSs = tokensIOSs.append(token.getToken());
					tokensIOSs = tokensIOSs.append("\",");
				}
			}
			tokensAndroid = tokensAndroids.toString();
			tokensIOS = tokensIOSs.toString();
			// 去掉最后多余的逗号，加上两边的中括号
			if (!tokensAndroid.equals("")) {
				tokensAndroid = tokensAndroid.substring(0, tokensAndroid.length() - 1);
				tokensAndroid = "[" + tokensAndroid + "]";
			}
			if (!tokensIOS.equals("")) {
				tokensIOS = tokensIOS.substring(0, tokensIOS.length() - 1);
				tokensIOS = "[" + tokensIOS + "]";
			}
		}

		// 给信鸽的消息
		JSONObject message = new JSONObject();
		
		message.put("content", JSONObject.fromObject(content).toString());
		message.put("title", "message");

		StringBuilder result = new StringBuilder();

		Map<String, String> params;
		// 给Android配送端推送消息
		if (!(tokensAndroid == null || tokensAndroid.equals(""))) {
			// 信鸽的message参数
			params = new HashMap<String, String>();
			params.put("account_list", tokensAndroid);
			params.put("message_type", "2"); // 消息类型：1：通知 2：透传消息
			params.put("message", message.toString());

			params.put("access_id", accessIdAndroid);
			Date date = new Date();
			String currentTime = String.valueOf(date.getTime() / 1000);
			params.put("timestamp", currentTime);
			String signString = sortParams(params);
			params.put("sign",
					MD5Util.string2MD5("POST" + XG_PUSH_URL + signString + secretKeyAndroid));

			String resultAndroidStr = HttpUtils.httpClientPostSend(XG_PUSH_ALL_URL, DEFAULT_CHARSET, params);
			JSONObject resultAndroid = JSONObject.fromObject(resultAndroidStr);

			result.append(resultAndroid.getInt("ret_code"));

		} else {
			result.append("none");
		}

		result.append(",");

		if (!(tokensIOS == null || tokensIOS.equals(""))) {
			//iOS平台推送需要加的参数
			JSONObject aps = new JSONObject();
			try {
				aps.put("alert",  content.getMsg());
				aps.put("sound", "default");

				message.put("aps", aps);
			} catch (Exception e) {
				e.printStackTrace();
			}
			// 信鸽的message参数
			params = new HashMap<String, String>();
			params.put("account_list", tokensIOS);
			params.put("message_type", "0"); // 消息类型：1：通知 2：透传消息。iOS平台请填0
			params.put("message", message.toString());

			params.put("environment", iOS_ENVIRENMENT); // 向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境

			params.put("access_id", accessIdIOS);
			Date date = new Date();
			String currentTime = String.valueOf(date.getTime() / 1000);
			params.put("timestamp", currentTime);
			String signString = sortParams(params);
			params.put("sign", MD5Util.string2MD5("POST" + XG_PUSH_URL + signString + secretKeyIOS));

			// 将信鸽返回的结果装换成json数组
			result.append(JSONObject.fromObject(content).toString());
		} else {
			result.append("none");
		}

		return result.toString();
	}

}
